package com.ruibang.glass.material.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.DictEntityInfo;
import com.ruibang.glass.common.domain.DictInfo;
import com.ruibang.glass.common.domain.UserInfo;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.camunda.BpmTaskApproveReq;
import com.ruibang.glass.common.utils.ApproveUserNameUtils;
import com.ruibang.glass.frequencycontrol.annotation.RedissonLock;
import com.ruibang.glass.material.constant.Constants;
import com.ruibang.glass.material.constant.MaterialErrorCode;
import com.ruibang.glass.material.constant.MaterialStatusCode;
import com.ruibang.glass.material.constant.MaterialWareHouseCode;
import com.ruibang.glass.material.domain.req.ApproveProcessReq;
import com.ruibang.glass.material.domain.req.ycl.ManageOutBoundReq;
import com.ruibang.glass.material.entity.*;
import com.ruibang.glass.material.feign.CamundaApi;
import com.ruibang.glass.material.feign.PortalApi;
import com.ruibang.glass.material.feign.PurchaseApi;
import com.ruibang.glass.material.mapper.GMaterialALLOutboundManagementMapper;
import com.ruibang.glass.material.mapper.MaterialAllOutboundItemMapper;
import com.ruibang.glass.material.mapper.MaterialWarehouseInventoryCheckMapper;
import com.ruibang.glass.material.service.*;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import com.teaming.cloud.framework2.common.tools.JsonUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.ruibang.glass.common.constants.RedisKey.MATERIAL_IN_WAREHOUSE_NUMBER;

/**
 * <p>
 * 出库管理表 服务实现类
 * </p>
 *
 * @author mameng
 * @since 2024-04-01
 */
@Service
public class GMaterialALLOutboundManagementServiceImpl extends ServiceImpl<GMaterialALLOutboundManagementMapper, MaterialALLOutboundManagement> implements GMaterialAllOutboundManagementService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private CamundaApi camundaApi;

    @Autowired
    private GMaterialALLInventoryManagementService materialALLInventoryManagementService;

    @Autowired
    private GMaterialManagementService materialManagementService;

    @Autowired
    private RedisSingleService redisService;

    @Autowired
    private PurchaseApi purchaseApi;

    @Autowired
    private MaterialAllOutboundItemMapper materialAllOutboundItemMapper;

    private final String CKSQMENUID = "w0235dokc6a011a6f2b5840cea000021";

    @Autowired
    private MaterialWarehouseInventoryCheckMapper materialWarehouseInventoryCheckMapper;

    @Autowired
    private MaterialWarehouseInfoService materialWarehouseInfoService;

    private static final String SALE_OUT_NUMBER = "sale_out_number";

    @Autowired
    private PortalApi portalApi;

    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * 列表
     *
     * @param materialInventoryReq
     * @return
     */
    @Override
    public IPage<MaterialALLOutboundManagement> getPage(ManageOutBoundReq materialInventoryReq) {
        LambdaQueryWrapper<MaterialALLOutboundManagement> queryWrapper = Wrappers.<MaterialALLOutboundManagement>lambdaQuery();
        if (StringUtils.isNotBlank(materialInventoryReq.getType())) {
            queryWrapper.like(MaterialALLOutboundManagement::getType, materialInventoryReq.getType());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getWarehouseName())) {
            queryWrapper.like(MaterialALLOutboundManagement::getWarehouseName, materialInventoryReq.getWarehouseName());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getOutNumber())) {
            queryWrapper.like(MaterialALLOutboundManagement::getOutNumber, materialInventoryReq.getOutNumber());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getOrderNumber())) {
            queryWrapper.like(MaterialALLOutboundManagement::getOutNumber, materialInventoryReq.getOrderNumber());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getStatus())) {
            queryWrapper.like(MaterialALLOutboundManagement::getStatus, materialInventoryReq.getStatus());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getApproveStatus())) {
            queryWrapper.like(MaterialALLOutboundManagement::getApproveStatus, materialInventoryReq.getApproveStatus());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getPreparer())) {
            queryWrapper.like(MaterialALLOutboundManagement::getPreparer, materialInventoryReq.getPreparer());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getBatchNumber())) {
            queryWrapper.like(MaterialALLOutboundManagement::getBatchNumber, materialInventoryReq.getBatchNumber());
        }

        if (StringUtils.isNotBlank(materialInventoryReq.getWareHouseStatus())) {
            queryWrapper.like(MaterialALLOutboundManagement::getWarehouseStatus, materialInventoryReq.getWareHouseStatus());
        }

        if (StringUtils.isNotBlank(materialInventoryReq.getWareHouseCode())) {
            queryWrapper.eq(MaterialALLOutboundManagement::getWarehouseCode, materialInventoryReq.getWareHouseCode());
            queryWrapper.eq(MaterialALLOutboundManagement::getOverStatus, Constants.ONE_STR);
        } else {
            queryWrapper.ne(MaterialALLOutboundManagement::getWarehouseCode, MaterialWareHouseCode.YCLK_CK.getMsg());
        }

        if (StringUtils.isNotBlank(materialInventoryReq.getItemName())) {
            queryWrapper.like(MaterialALLOutboundManagement::getItemName, materialInventoryReq.getItemName());
        }
        if (StringUtils.isNotBlank(materialInventoryReq.getBarcodeNumber())) {
            queryWrapper.like(MaterialALLOutboundManagement::getBarcodeNumber, materialInventoryReq.getBarcodeNumber());
        }
        if (materialInventoryReq.getFinishStartDate() != null) {
            queryWrapper.ge(MaterialALLOutboundManagement::getFinishDate, materialInventoryReq.getFinishStartDate());
        }
        if (materialInventoryReq.getFinishEndDate() != null) {
            queryWrapper.le(MaterialALLOutboundManagement::getFinishDate, materialInventoryReq.getFinishEndDate());
        }
        Page<MaterialALLOutboundManagement> materialWarehouseInfoPage = baseMapper.selectPage(new Page<>(materialInventoryReq.getPageNo(), materialInventoryReq.getPageSize()),
                queryWrapper.orderByDesc(MaterialALLOutboundManagement::getCreateTime)
        );

        if (CollectionUtils.isEmpty(materialWarehouseInfoPage.getRecords())) {
            return materialWarehouseInfoPage;
        }
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        List<String> businessKeys = materialWarehouseInfoPage.getRecords().stream().map(MaterialALLOutboundManagement::getId).collect(Collectors.toList());
        Map<String, BpmProcessInstanceStatus> processMap = null;
        //获取业务流程状态
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(businessKeys);
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
        }
        //先获取当前下的物料
        for (MaterialALLOutboundManagement materialALLOutboundManagement : materialWarehouseInfoPage.getRecords()) {

            if (StringUtils.isNotEmpty(materialALLOutboundManagement.getWarehousePerson())) {
                if (!StringUtils.equals(materialALLOutboundManagement.getWarehousePerson(), "null")) {
                    String approveName = ApproveUserNameUtils.getApproveName(materialALLOutboundManagement.getWarehousePerson(), userMap);
                    materialALLOutboundManagement.setWarehousePerson(approveName);
                }
            }
            if (StringUtils.isNotEmpty(materialALLOutboundManagement.getWarehouseLeader())) {
                if (!StringUtils.equals(materialALLOutboundManagement.getWarehouseLeader(), "null")) {
                    String approveName = ApproveUserNameUtils.getApproveName(materialALLOutboundManagement.getWarehouseLeader(), userMap);
                    materialALLOutboundManagement.setWarehouseLeader(approveName);
                }
            }

            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().select(MaterialAllOutboundItem::getWarehouseId).eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
            //获取仓库管理员
            if (CollectionUtils.isNotEmpty(materialAllOutboundItems)) {
                List<String> warehouseIdList = new ArrayList<>();
                for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                    if (materialAllOutboundItem != null) {
                        if (StringUtils.isNotEmpty(materialAllOutboundItem.getWarehouseId())) {
                            warehouseIdList.add(materialAllOutboundItem.getWarehouseId());
                        }
                    }
                }
                if (CollectionUtils.isNotEmpty(warehouseIdList)) {
                    List<MaterialWarehouseInfo> list = materialWarehouseInfoService.list(Wrappers.<MaterialWarehouseInfo>lambdaQuery().select(MaterialWarehouseInfo::getId, MaterialWarehouseInfo::getWarehouseName, MaterialWarehouseInfo::getAdministrator).in(MaterialWarehouseInfo::getId, warehouseIdList));
                    String collect = list.stream().map(MaterialWarehouseInfo::getAdministrator).collect(Collectors.joining(","));
                    String warehouseName = list.stream().map(MaterialWarehouseInfo::getWarehouseName).collect(Collectors.joining(","));
                    if (StringUtils.isNotEmpty(collect) && !StringUtils.equals(collect, "null")) {
//                        String approveName = ApproveUserNameUtils.getApproveName(collect, userMap);
//                        materialALLOutboundManagement.setWarehouseLeader(approveName);
//                        materialALLOutboundManagement.setWarehousePerson(approveName);
                        materialALLOutboundManagement.setWarehouseName(warehouseName);
                    }
                }
            }
        }

        if (processMap != null) {
            for (MaterialALLOutboundManagement materialALLOutboundManagement : materialWarehouseInfoPage.getRecords()) {
                if (processMap.get(materialALLOutboundManagement.getId()) != null) {
                    materialALLOutboundManagement.setStatus(String.valueOf(processMap.get(materialALLOutboundManagement.getId()).getStatus()));
                    materialALLOutboundManagement.setProcessId(processMap.get(materialALLOutboundManagement.getId()).getProcessInstanceId());
//                    materialALLOutboundManagement.setApproveStatus(processMap.get(materialALLOutboundManagement.getId()).getResult());
                    materialALLOutboundManagement.setNodeName(processMap.get(materialALLOutboundManagement.getId()).getNodeName());
                    if (StringUtils.isNotEmpty(processMap.get(materialALLOutboundManagement.getId()).getUserId())) {
                        String userId = processMap.get(materialALLOutboundManagement.getId()).getUserId();
                        if (StringUtils.isNotEmpty(userId) && !StringUtils.equals(userId, "null")) {
                            String approveName = ApproveUserNameUtils.getApproveName(userId, userMap);
                            materialALLOutboundManagement.setApproveUser(approveName);
                            materialALLOutboundManagement.setApproveUserId(userId);
                        }
                    }
                }
            }
        }
        return materialWarehouseInfoPage;
    }


//    @Override
//    public IPage<OutAndInManagementDTO> getPage(ManageOutInReq manageOutInReq) {
//        return baseMapper.getPage(new Page<>(manageOutInReq.hashCode(), manageOutInReq.getPageSize()), manageOutInReq);
//    }

    /**
     * 状态更改
     *
     * @param id
     * @return
     */
    public String getApproveStatus(String id) {
        List<String> ids = new ArrayList<>();
        ids.add(id);
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(ids);
        Map<String, String> approveStatusMap = null;
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            approveStatusMap = resultBody.getData().stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, BpmProcessInstanceStatus::getResult, (s1, s2) -> s1));
        }
        if (approveStatusMap.get(id) != null) {
            return approveStatusMap.get(id);
        }
        return "";
    }


    @Override
    public String approveProcess(ApproveProcessReq approveProcessReq) {
        BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
        instanceCreate.setBusinessKey(approveProcessReq.getBusinessKey());
        instanceCreate.setMenuId(approveProcessReq.getMenuId());
        //发起流程
        if (StringUtils.isNotBlank(approveProcessReq.getPreparerId())) {
            Map<String, Object> variables = new HashMap<>();
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, approveProcessReq.getPreparerId());
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, approveProcessReq.getBusinessKey());
            variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, approveProcessReq.getMenuId());
            instanceCreate.setVariables(variables);
        }
        return commonService.startProcess(instanceCreate);
    }


    /**
     * 新建流程
     *
     * @param materialALLOutboundManagement
     * @return
     */
    @Override
    public ResultBody addMaterialZPKOutboundManagement(MaterialALLOutboundManagement materialALLOutboundManagement) {
        List<MaterialALLOutboundManagement> execute = transactionTemplate.execute(tran -> {
            if (CollectionUtils.isEmpty(materialALLOutboundManagement.getMaterialAllOutboundItemList())) {
                throw new ServiceException(MaterialStatusCode.NO_ITEM.getCode(), MaterialStatusCode.NO_ITEM.getMsg());
            }
            Map<MaterialAllOutboundItem, Integer> map = new HashMap<>();
            //校验是否有同物品同库位的情况存在
            List<MaterialAllOutboundItem> materialAllOutboundItemList = materialALLOutboundManagement.getMaterialAllOutboundItemList();
            for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItemList) {
                MaterialAllOutboundItem newMaterialAllOutboundItem = new MaterialAllOutboundItem();
                newMaterialAllOutboundItem.setItemCode(materialAllOutboundItem.getItemCode());
                newMaterialAllOutboundItem.setStorageLocationId(materialAllOutboundItem.getStorageLocationId());
                if (map.get(newMaterialAllOutboundItem) == null) {
                    map.put(newMaterialAllOutboundItem, Constants.ONE_INT);
                } else {
                    throw new ServiceException(MaterialErrorCode.SAME_ITEM_SAME_STORAGE.getCode(), MaterialErrorCode.SAME_ITEM_SAME_STORAGE.getMsg());
                }
            }
            Map<String, List<MaterialAllOutboundItem>> collect = materialALLOutboundManagement.getMaterialAllOutboundItemList().stream().collect(Collectors.groupingBy(MaterialAllOutboundItem::getWarehouseCode));
            List<MaterialALLOutboundManagement> materialALLOutboundManagementsList = new ArrayList<>();
            for (String warehouseCode : collect.keySet()) {
                materialALLOutboundManagement.setWarehouseCode(warehouseCode);
                materialALLOutboundManagement.setMaterialAllOutboundItemList(collect.get(warehouseCode));
                String outNumber = getOutNumber();
                materialALLOutboundManagement.setOutNumber(outNumber);
                materialALLOutboundManagement.setSpStatus(Constants.ONE_STR);
//                if (StringUtils.isNotEmpty(materialALLOutboundManagement.getId())) {
//                    materialALLOutboundManagement.setId("");
//                }
                baseMapper.insert(materialALLOutboundManagement);
                MaterialALLOutboundManagement materialALLOutboundManagementRe = new MaterialALLOutboundManagement();
                BeanUtils.copyProperties(materialALLOutboundManagement, materialALLOutboundManagementRe);
                materialALLOutboundManagementsList.add(materialALLOutboundManagementRe);
                for (MaterialAllOutboundItem materialAllOutboundItem : collect.get(warehouseCode)) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialALLOutboundManagement.getWarehouseCode())
                            .last("limit 1")
                    );
                    if (one.getAvailableQuantity() == null) {
                        if (one.getStockQuantity() == null) {
                            throw new ServiceException(MaterialStatusCode.NO_USE_QUALITY.getCode(), MaterialStatusCode.NO_USE_QUALITY.getMsg());
                        }
                        one.setAvailableQuantity(BigDecimal.valueOf(one.getStockQuantity()));
                    }
                    if (one.getAvailableQuantity().compareTo(materialAllOutboundItem.getQuantity()) < 0) {
                        throw new ServiceException(MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getCode(), MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getMsg());
                    }
                    BigDecimal subtract = one.getAvailableQuantity().subtract(materialAllOutboundItem.getQuantity());
                    one.setAvailableQuantity(subtract);
                    if (one.getFrozenQuantity() == null) {
                        one.setFrozenQuantity(materialAllOutboundItem.getQuantity());
                    } else {
                        BigDecimal add = one.getFrozenQuantity().add(materialAllOutboundItem.getQuantity());
                        one.setFrozenQuantity(add);
                    }
                    materialAllOutboundItem.setOutAllId(materialALLOutboundManagement.getId());
                    materialALLInventoryManagementService.updateById(one);
                    materialAllOutboundItemMapper.insert(materialAllOutboundItem);
                }
                materialALLOutboundManagement.setId("");
            }
            return materialALLOutboundManagementsList;
        });
        if (CollectionUtils.isNotEmpty(execute)) {
//            for (MaterialALLOutboundManagement materialALLOutboundManagement1 : execute) {
//                BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
//                instanceCreate.setBusinessKey(materialALLOutboundManagement1.getId());
//                instanceCreate.setMenuId(materialALLOutboundManagement1.getMenuId());
//                //发起流程
//                if (StringUtils.isNotBlank(materialALLOutboundManagement.getPreparerId())) {
//                    Map<String, Object> variables = new HashMap<>();
//                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, materialALLOutboundManagement1.getPreparerId());
//                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, materialALLOutboundManagement1.getId());
//                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, materialALLOutboundManagement1.getMenuId());
//                    instanceCreate.setVariables(variables);
//                }
//                commonService.startProcess(instanceCreate);
//            }
        }
        return ResultBody.success(MaterialStatusCode.ADD_SUCCESS_OUT.getMsg());
    }


    @Override
    public ResultBody addByPurchaseReturn(MaterialALLOutboundManagement materialALLOutboundManagement) {
        MaterialALLOutboundManagement execute = transactionTemplate.execute(tran -> {
            Map<String, List<MaterialAllOutboundItem>> collect = materialALLOutboundManagement.getMaterialAllOutboundItemList().stream().collect(Collectors.groupingBy(MaterialAllOutboundItem::getWarehouseCode));
            for (String warehouseCode : collect.keySet()) {
                materialALLOutboundManagement.setWarehouseCode(warehouseCode);
                materialALLOutboundManagement.setMaterialAllOutboundItemList(collect.get(warehouseCode));
                String outNumber = getOutNumber();
                materialALLOutboundManagement.setOutNumber(outNumber);
                materialALLOutboundManagement.setSpStatus(Constants.ONE_STR);
                baseMapper.insert(materialALLOutboundManagement);
                for (MaterialAllOutboundItem materialAllOutboundItem : collect.get(warehouseCode)) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialALLOutboundManagement.getWarehouseCode())
                            .last("limit 1")
                    );
                    if (one != null) {
                        if (one.getAvailableQuantity() == null) {
                            if (one.getStockQuantity() == null) {
                                throw new ServiceException(MaterialStatusCode.NO_USE_QUALITY.getCode(), MaterialStatusCode.NO_USE_QUALITY.getMsg());
                            }
                            one.setAvailableQuantity(BigDecimal.valueOf(one.getStockQuantity()));
                        }
                        if (one.getAvailableQuantity().compareTo(materialAllOutboundItem.getQuantity()) < 0) {
                            throw new ServiceException(MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getCode(), MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getMsg());
                        }
                        BigDecimal subtract = one.getAvailableQuantity().subtract(materialAllOutboundItem.getQuantity());
                        one.setAvailableQuantity(subtract);
                        if (one.getFrozenQuantity() == null) {
                            one.setFrozenQuantity(materialAllOutboundItem.getQuantity());
                        } else {
                            BigDecimal add = one.getFrozenQuantity().add(materialAllOutboundItem.getQuantity());
                            one.setFrozenQuantity(add);
                        }
                        materialAllOutboundItem.setOutAllId(materialALLOutboundManagement.getId());
                        materialALLInventoryManagementService.updateById(one);
                        if (StringUtils.isEmpty(materialAllOutboundItem.getWarehouseId()) && StringUtils.isNotEmpty(materialAllOutboundItem.getWarehouseName())) {
                            MaterialWarehouseInfo one1 = materialWarehouseInfoService.getOne(Wrappers.<MaterialWarehouseInfo>lambdaQuery().eq(MaterialWarehouseInfo::getWarehouseName, materialAllOutboundItem.getWarehouseName()).last("limit 1"));
                            if (one1 != null) {
                                materialAllOutboundItem.setWarehouseId(one1.getId());
                            }
                        }
                        materialAllOutboundItemMapper.insert(materialAllOutboundItem);
                    }
                }
            }
            return materialALLOutboundManagement;
        });
        if (materialALLOutboundManagement != null) {
            Map<String, List<MaterialAllOutboundItem>> collect = materialALLOutboundManagement.getMaterialAllOutboundItemList().stream().collect(Collectors.groupingBy(MaterialAllOutboundItem::getWarehouseCode));
            for (String warehouseCode : collect.keySet()) {
                BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
                instanceCreate.setBusinessKey(materialALLOutboundManagement.getId());
                instanceCreate.setMenuId(materialALLOutboundManagement.getMenuId());
                //发起流程
                if (StringUtils.isNotBlank(materialALLOutboundManagement.getUsePersonId())) {
                    Map<String, Object> variables = new HashMap<>();
                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, materialALLOutboundManagement.getUsePersonId());
                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, materialALLOutboundManagement.getId());
                    variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, materialALLOutboundManagement.getMenuId());
                    instanceCreate.setVariables(variables);
                }
                commonService.startProcess(instanceCreate);
                String processId = commonService.startProcess(instanceCreate);
                //跳过第一个流程
                if (StringUtils.isNotBlank(processId)) {
                    BpmTaskApproveReq bpmTaskApproveReq = new BpmTaskApproveReq();
                    bpmTaskApproveReq.setId(processId);
                    bpmTaskApproveReq.setUserId(materialALLOutboundManagement.getUsePersonId());
                    materialALLOutboundManagement.setApproveStatus(com.ruibang.glass.common.constants.Constants.ONE_STR);
                    baseMapper.updateById(materialALLOutboundManagement);
                    camundaApi.approve(bpmTaskApproveReq);
                }

                //跳过第二个流程
                if (StringUtils.isNotBlank(processId)) {
                    BpmTaskApproveReq bpmTaskApproveReq = new BpmTaskApproveReq();
                    bpmTaskApproveReq.setId(processId);
                    bpmTaskApproveReq.setUserId(materialALLOutboundManagement.getUsePersonId());
                    materialALLOutboundManagement.setApproveStatus(com.ruibang.glass.common.constants.Constants.ONE_STR);
                    materialALLOutboundManagement.setOverStatus(com.ruibang.glass.common.constants.Constants.ONE_STR);
                    materialALLOutboundManagement.setOutStatus(com.ruibang.glass.common.constants.Constants.ONE_STR);
                    baseMapper.updateById(materialALLOutboundManagement);
                    camundaApi.approve(bpmTaskApproveReq);
                }
            }
        }
        return ResultBody.success(MaterialStatusCode.ADD_SUCCESS_OUT.getMsg());
    }

    @Override
    public void processNotice(String businessId) {
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Arrays.asList(businessId));
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            BpmProcessInstanceStatus process = resultBody.getData().get(0);
            if (process.getNodeKey().equals("Activity_0yxlb4d")) {
                MaterialALLOutboundManagement materialALLOutboundManagement = baseMapper.selectById(businessId);
                materialALLOutboundManagement.setOverStatus(Constants.ONE_STR);
                baseMapper.updateById(materialALLOutboundManagement);
            }
        }
        MaterialALLOutboundManagement materialALLOutboundManagement = baseMapper.selectById(businessId);
        if (materialALLOutboundManagement.getApproveStatus().equals(Constants.FOUR_STR)) {
            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
            if (materialALLOutboundManagement.getWarehouseCode().equals(MaterialWareHouseCode.YCLK_CK.getMsg())) {
                for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getBatchNumber, materialAllOutboundItem.getBatchNumber())
                            .eq(MaterialALLInventoryManagement::getBarcodeNumber, materialAllOutboundItem.getBarcodeNumber())
                            .last("limit 1")
                    );
                    if (one != null) {
                        if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                            BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                            BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                            one.setFrozenQuantity(subtract);
                            one.setAvailableQuantity(add);
                            materialALLInventoryManagementService.updateById(one);
                        }

                    }
                }
            } else {
                for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .last("limit 1")
                    );
                    if (one != null) {
                        if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                            BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                            BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                            one.setFrozenQuantity(subtract);
                            one.setAvailableQuantity(add);
                            materialALLInventoryManagementService.updateById(one);
                        }
                    }
                }
            }
            materialALLOutboundManagement.setFinishDate(LocalDateTime.now());
            baseMapper.updateById(materialALLOutboundManagement);
        }
    }

    @Override
    public void processYCLNotice(String businessId) {
        MaterialALLOutboundManagement materialALLOutboundManagement = baseMapper.selectById(businessId);
        if (materialALLOutboundManagement.getApproveStatus().equals(Constants.FOUR_STR)) {
            List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
            if (materialALLOutboundManagement.getWarehouseCode().equals(MaterialWareHouseCode.YCLK_CK.getMsg())) {
                for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .eq(MaterialALLInventoryManagement::getBatchNumber, materialAllOutboundItem.getBatchNumber())
                            .eq(MaterialALLInventoryManagement::getBarcodeNumber, materialAllOutboundItem.getBarcodeNumber())
                            .last("limit 1")
                    );
                    if (one != null) {
                        if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                            BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                            BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                            one.setFrozenQuantity(subtract);
                            one.setAvailableQuantity(add);
                            materialALLInventoryManagementService.updateById(one);
                        }

                    }
                }
            } else {
                for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                    MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                            .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                            .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                            .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                            .last("limit 1")
                    );
                    if (one != null) {
                        if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                            BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                            BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                            one.setFrozenQuantity(subtract);
                            one.setAvailableQuantity(add);
                            materialALLInventoryManagementService.updateById(one);
                        }
                    }
                }
            }
            materialALLOutboundManagement.setFinishDate(LocalDateTime.now());
            baseMapper.updateById(materialALLOutboundManagement);
        }
    }


    @Override
    public ResultBody addMaterialYClOutboundManagement(MaterialALLOutboundManagement materialALLOutboundManagement) {
        String execute = transactionTemplate.execute(tran -> {
            materialALLOutboundManagement.setWarehouseCode(MaterialWareHouseCode.YCLK_CK.getMsg());
            materialALLOutboundManagement.setSpStatus(Constants.ONE_STR);
            materialALLOutboundManagement.setOverStatus(Constants.ONE_STR);
            materialALLOutboundManagement.setPreparerId(materialALLOutboundManagement.getUsePersonId());
            materialALLOutboundManagement.setPreparer(materialALLOutboundManagement.getUsePerson());
            baseMapper.insert(materialALLOutboundManagement);
            for (MaterialAllOutboundItem materialAllOutboundItem : materialALLOutboundManagement.getMaterialAllOutboundItemList()) {
                MaterialManagement byId = materialManagementService.getById(materialAllOutboundItem.getItemId());
                materialAllOutboundItem.setOutAllId(materialALLOutboundManagement.getId());
                materialAllOutboundItem.setItemCode(byId.getMaterialCode());
                materialAllOutboundItem.setWarehouseCode(MaterialWareHouseCode.YCLK_CK.getMsg());
                materialAllOutboundItem.setWarehouseId(materialALLOutboundManagement.getWarehouseId());
                materialAllOutboundItem.setWarehouseName(materialALLOutboundManagement.getWarehouseName());
                materialAllOutboundItemMapper.insert(materialAllOutboundItem);
                // 在此过程计算可用数
            }
            return Constants.ONE_STR;
        });
        if (StringUtils.equals(execute, Constants.ONE_STR)) {
            BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
            instanceCreate.setBusinessKey(materialALLOutboundManagement.getId());
            instanceCreate.setMenuId(CKSQMENUID);
            //发起流程
            if (StringUtils.isNotBlank(materialALLOutboundManagement.getUsePersonId())) {
                Map<String, Object> variables = new HashMap<>();
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, materialALLOutboundManagement.getUsePersonId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, materialALLOutboundManagement.getId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, CKSQMENUID);
                instanceCreate.setVariables(variables);
            }
            commonService.startProcess(instanceCreate);
        }
        return ResultBody.success(MaterialStatusCode.ADD_SUCCESS_OUT.getMsg());
    }


    @Override
    public ResultBody addByPurchaseYclList(MaterialALLOutboundManagement materialALLOutboundManagement) {
        String execute = transactionTemplate.execute(tran -> {
            materialALLOutboundManagement.setWarehouseCode(MaterialWareHouseCode.YCLK_CK.getMsg());
            materialALLOutboundManagement.setSpStatus(Constants.ONE_STR);
            materialALLOutboundManagement.setOverStatus(Constants.ONE_STR);
            materialALLOutboundManagement.setPreparerId(materialALLOutboundManagement.getUsePersonId());
            materialALLOutboundManagement.setPreparer(materialALLOutboundManagement.getUsePerson());
            baseMapper.insert(materialALLOutboundManagement);
            for (MaterialAllOutboundItem materialAllOutboundItem : materialALLOutboundManagement.getMaterialAllOutboundItemList()) {
                MaterialManagement byId = materialManagementService.getById(materialAllOutboundItem.getItemId());
                materialAllOutboundItem.setOutAllId(materialALLOutboundManagement.getId());
//                materialAllOutboundItem.setItemCode(byId.getMaterialCode());
                materialAllOutboundItem.setWarehouseCode(MaterialWareHouseCode.YCLK_CK.getMsg());
                materialAllOutboundItem.setWarehouseId(materialALLOutboundManagement.getWarehouseId());
                materialAllOutboundItem.setWarehouseName(materialALLOutboundManagement.getWarehouseName());
                materialAllOutboundItemMapper.insert(materialAllOutboundItem);
                // 在此过程计算可用数
            }
            return Constants.ONE_STR;
        });
        if (StringUtils.equals(execute, Constants.ONE_STR)) {
            BpmProcessInstanceCreate instanceCreate = new BpmProcessInstanceCreate();
            instanceCreate.setBusinessKey(materialALLOutboundManagement.getId());
            instanceCreate.setMenuId(CKSQMENUID);
            //发起流程
            if (StringUtils.isNotBlank(materialALLOutboundManagement.getUsePersonId())) {
                Map<String, Object> variables = new HashMap<>();
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_STARTER_USER_ID, materialALLOutboundManagement.getUsePersonId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_BUSINESS_KEY, materialALLOutboundManagement.getId());
                variables.put(com.ruibang.glass.common.constants.Constants.PROCESS_INSTANCE_MENU_ID, CKSQMENUID);
                instanceCreate.setVariables(variables);
            }
            commonService.startProcess(instanceCreate);
        }
        return ResultBody.success(MaterialStatusCode.ADD_SUCCESS_OUT.getMsg());
    }

    @Override
    public MaterialALLOutboundManagement getMaterialALLOutboundManagementById(String id) {
        MaterialALLOutboundManagement materialALLOutboundManagement = baseMapper.selectById(id);
        List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, id));
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        if (CollectionUtils.isNotEmpty(materialAllOutboundItems)) {
            List<String> warehouseIdList = new ArrayList<>();
            for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                if (materialAllOutboundItem != null) {
                    if (StringUtils.isNotEmpty(materialAllOutboundItem.getWarehouseId())) {
                        warehouseIdList.add(materialAllOutboundItem.getWarehouseId());
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(warehouseIdList)) {
                List<MaterialWarehouseInfo> list = materialWarehouseInfoService.list(Wrappers.<MaterialWarehouseInfo>lambdaQuery().select(MaterialWarehouseInfo::getId, MaterialWarehouseInfo::getWarehouseName, MaterialWarehouseInfo::getAdministrator).in(MaterialWarehouseInfo::getId, warehouseIdList));
                String collect = list.stream().map(MaterialWarehouseInfo::getAdministrator).collect(Collectors.joining(","));
                String warehouseName = list.stream().map(MaterialWarehouseInfo::getWarehouseName).collect(Collectors.joining(","));
                if (StringUtils.isNotEmpty(collect) && !StringUtils.equals(collect, "null")) {
                    String approveName = ApproveUserNameUtils.getApproveName(collect, userMap);
                    materialALLOutboundManagement.setWarehouseLeader(approveName);
                    materialALLOutboundManagement.setWarehousePerson(approveName);
                    materialALLOutboundManagement.setWarehouseName(warehouseName);
                }
            }
        }
        materialALLOutboundManagement.setMaterialAllOutboundItemList(materialAllOutboundItems);
        return materialALLOutboundManagement;
    }

    /**
     * 跟新
     *
     * @param materialALLOutboundManagement
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMaterialZPKOutboundManagement(MaterialALLOutboundManagement materialALLOutboundManagement) {
        Map<MaterialAllOutboundItem, Integer> map = new HashMap<>();
        for (MaterialAllOutboundItem materialAllOutboundItem : materialALLOutboundManagement.getMaterialAllOutboundItemList()) {
            MaterialAllOutboundItem newMaterialAllOutboundItem = new MaterialAllOutboundItem();
            newMaterialAllOutboundItem.setItemCode(materialAllOutboundItem.getItemCode());
            newMaterialAllOutboundItem.setStorageLocationId(materialAllOutboundItem.getStorageLocationId());
            if (map.get(newMaterialAllOutboundItem) == null) {
                map.put(newMaterialAllOutboundItem, Constants.ONE_INT);
            } else {
                throw new ServiceException(MaterialErrorCode.SAME_ITEM_SAME_STORAGE.getCode(), MaterialErrorCode.SAME_ITEM_SAME_STORAGE.getMsg());
            }
        }

        MaterialALLOutboundManagement materialZPKOutboundManagement1 = baseMapper.selectById(materialALLOutboundManagement.getId());
        materialZPKOutboundManagement1.setRemarks(materialALLOutboundManagement.getRemarks());

        if (CollectionUtils.isEmpty(materialALLOutboundManagement.getMaterialAllOutboundItemList())) {
            throw new ServiceException(MaterialStatusCode.NO_ITEM.getCode(), MaterialStatusCode.NO_ITEM.getMsg());
        }
        //先解冻在冻结
        List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
        for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
            MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                    .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                    .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                    .eq(MaterialALLInventoryManagement::getWareHouseCode, materialALLOutboundManagement.getWarehouseCode())
                    .last("limit 1")
            );
            if (one != null) {
                if (one.getFrozenQuantity() != null) {
                    if (one.getFrozenQuantity().compareTo(materialAllOutboundItem.getQuantity()) > 0) {
                        BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                        one.setFrozenQuantity(subtract);
                    }
                }
                if (one.getAvailableQuantity() != null) {
                    BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                    one.setAvailableQuantity(add);
                }
            }
            materialALLInventoryManagementService.updateById(one);
        }

        for (MaterialAllOutboundItem materialAllOutboundItem : materialALLOutboundManagement.getMaterialAllOutboundItemList()) {
            MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                    .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                    .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                    .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                    .last("limit 1")
            );
            if (one.getAvailableQuantity() == null) {
                if (one.getStockQuantity() == null) {
                    throw new ServiceException(MaterialStatusCode.NO_USE_QUALITY.getCode(), MaterialStatusCode.NO_USE_QUALITY.getMsg());
                }
                one.setAvailableQuantity(BigDecimal.valueOf(one.getStockQuantity()));
            }
            if (one.getAvailableQuantity().compareTo(materialAllOutboundItem.getQuantity()) < 0) {
                throw new ServiceException(MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getCode(), MaterialStatusCode.USE_QUALITY_LESS_OUT_USE.getMsg());
            }
            BigDecimal subtract = one.getAvailableQuantity().subtract(materialAllOutboundItem.getQuantity());
            one.setAvailableQuantity(subtract);
            if (one.getFrozenQuantity() == null) {
                one.setFrozenQuantity(materialAllOutboundItem.getQuantity());
            } else {
                BigDecimal add = one.getFrozenQuantity().add(materialAllOutboundItem.getQuantity());
                one.setFrozenQuantity(add);
            }
            materialAllOutboundItem.setOutAllId(materialALLOutboundManagement.getId());
            materialALLInventoryManagementService.updateById(one);
            if (StringUtils.isNotEmpty(materialAllOutboundItem.getId())) {
                materialAllOutboundItemMapper.updateById(materialAllOutboundItem);
            } else {
                materialAllOutboundItemMapper.insert(materialAllOutboundItem);
            }
        }
        baseMapper.updateById(materialZPKOutboundManagement1);
    }

    /**
     * 计算库存
     *
     * @param materialZPKOutboundManagement
     */
    //计算库存
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateItemHouse(MaterialALLOutboundManagement materialZPKOutboundManagement) {
        //检验流程是否结束
//        String approveStatus = getApproveStatus(materialZPKOutboundManagement.getId());
//        if (!StringUtils.equals(approveStatus, Constants.TWO_STR)) {
//            return;
//        }
        List<String> returnIdList = new ArrayList<>();
        MaterialALLOutboundManagement materialZPKOutboundManagement1 = baseMapper.selectById(materialZPKOutboundManagement.getId());
        List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialZPKOutboundManagement.getId()));
        for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
            MaterialALLInventoryManagement one = new MaterialALLInventoryManagement();
            if (materialZPKOutboundManagement1.getWarehouseCode().equals(MaterialWareHouseCode.YCLK_CK.getMsg())) {
                one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .eq(MaterialALLInventoryManagement::getWareHouseCode, MaterialWareHouseCode.YCLK_CK.getMsg())
                        .eq(MaterialALLInventoryManagement::getBatchNumber, materialAllOutboundItem.getBatchNumber())
                        .eq(MaterialALLInventoryManagement::getBarcodeNumber, materialAllOutboundItem.getBarcodeNumber())
                        .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                        .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode()).last("limit 1"));
            } else {
                one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                        .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                        .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode()).last("limit 1"));
            }
            if (one == null) {
                throw new ServiceException(MaterialStatusCode.NO_MATERIAL_QUALITY.getCode(), MaterialStatusCode.NO_MATERIAL_QUALITY.getMsg());
            }
            if (materialAllOutboundItem.getQuantity() == null) {
                throw new ServiceException(MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getCode(), MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getMsg());
            }
            if (one.getStockQuantity() == null) {
                throw new ServiceException(MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getCode(), MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getMsg());
            }
            if (materialAllOutboundItem.getQuantity().intValue() > one.getStockQuantity()) {
                throw new ServiceException(MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getCode(), MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getMsg());
            }
            Integer subQuality = one.getStockQuantity() - materialAllOutboundItem.getQuantity().intValue();
            if (one.getFrozenQuantity() != null) {
                BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                one.setFrozenQuantity(subtract);
            }
            one.setStockQuantity(subQuality);
            materialALLInventoryManagementService.updateById(one);
            // 完成出库调整采购到货的数据
            if (StringUtils.isNotEmpty(materialAllOutboundItem.getReturnId())) {
                returnIdList.add(materialAllOutboundItem.getReturnId());
            }
        }
        if (CollectionUtils.isNotEmpty(returnIdList)) {
            purchaseApi.updateOrderQuality(returnIdList);
        }

        materialZPKOutboundManagement1.setFinishDate(LocalDateTime.now());
        materialZPKOutboundManagement1.setOutStatus(Constants.TWO_STR);
        baseMapper.updateById(materialZPKOutboundManagement1);
    }


    @Override
    public void deleteChooseIds(List<String> ids) {
        List<MaterialALLOutboundManagement> materialALLOutboundManagements = baseMapper.selectBatchIds(ids);
        for (MaterialALLOutboundManagement materialALLOutboundManagement : materialALLOutboundManagements) {
            if (!StringUtils.equals(materialALLOutboundManagement.getApproveStatus(), Constants.ZERO_STR)) {
                throw new ServiceException(MaterialStatusCode.DELETE_APPROVE_OVER.getCode(), MaterialStatusCode.DELETE_APPROVE_OVER.getMsg());
            }
        }
        if (CollectionUtils.isNotEmpty(materialALLOutboundManagements)) {
            for (MaterialALLOutboundManagement materialALLOutboundManagement : materialALLOutboundManagements) {
                List<MaterialAllOutboundItem> materialAllOutboundItems = materialAllOutboundItemMapper.selectList(Wrappers.<MaterialAllOutboundItem>lambdaQuery().eq(MaterialAllOutboundItem::getOutAllId, materialALLOutboundManagement.getId()));
                if (materialALLOutboundManagement.getWarehouseCode().equals(MaterialWareHouseCode.YCLK_CK.getMsg())) {
                    for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                        MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                                .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                                .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                                .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                                .eq(MaterialALLInventoryManagement::getBatchNumber, materialAllOutboundItem.getBatchNumber())
                                .eq(MaterialALLInventoryManagement::getBarcodeNumber, materialAllOutboundItem.getBarcodeNumber())
                                .last("limit 1")
                        );
                        if (one != null) {
                            if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                                BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                                BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                                one.setFrozenQuantity(subtract);
                                one.setAvailableQuantity(add);
                                materialALLInventoryManagementService.updateById(one);
                            }

                        }

                    }
                } else {
                    for (MaterialAllOutboundItem materialAllOutboundItem : materialAllOutboundItems) {
                        MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                                .eq(MaterialALLInventoryManagement::getWareHouseCode, materialAllOutboundItem.getWarehouseCode())
                                .eq(MaterialALLInventoryManagement::getStorageLocation, materialAllOutboundItem.getStorageLocationId())
                                .eq(MaterialALLInventoryManagement::getMaterialCode, materialAllOutboundItem.getItemCode())
                                .last("limit 1")
                        );
                        if (one != null) {
                            if (one.getFrozenQuantity() != null && one.getAvailableQuantity() != null) {
                                BigDecimal subtract = one.getFrozenQuantity().subtract(materialAllOutboundItem.getQuantity());
                                BigDecimal add = one.getAvailableQuantity().add(materialAllOutboundItem.getQuantity());
                                one.setFrozenQuantity(subtract);
                                one.setAvailableQuantity(add);
                                materialALLInventoryManagementService.updateById(one);
                            }

                        }

                    }
                }
            }
        }
        baseMapper.deleteBatchIds(ids);
    }

    @Override
    public ResultBody getDictList() {
        List<DictEntityInfo> list = JsonUtils.parseArray((String) redisService.get(RedisKey.DICT_NEW_GROUP_TYPE), DictEntityInfo.class);
        return ResultBody.success(list);
    }

    @Override
    public List<UserInfo> getUserInfoList() {
        Map<Object, Object> hmget = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        List<UserInfo> userInfoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(hmget)) {
            for (Object obj : hmget.keySet()) {
                UserInfo userInfo = new UserInfo();
                userInfo.setUserId((String) obj);
                userInfo.setUserName((String) hmget.get(obj));
                userInfoList.add(userInfo);
            }
        }
        return userInfoList;

    }

    @Override
    public String getOutNumber() {
        String materialOUTNumber = getMaterialOUTNumber();
        return materialOUTNumber;
    }

    @RedissonLock(key = MATERIAL_IN_WAREHOUSE_NUMBER, prefixKey = "lock_")
    public String getMaterialOUTNumber() {
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern(CommonConstant.DATE_FORMAT_UN_SEPARATE));
        date = "OUT".concat(date);
        String code = "";

        Serializable number = redisService.get(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER);
        if (number == null || StringUtils.isBlank(number.toString())) {
            ResultBody<String> resultBody = portalApi.getValueByCode(SALE_OUT_NUMBER);
            if (resultBody != null && StringUtils.isNotBlank(resultBody.getData())) {
                number = resultBody.getData();
            }
        }
        if (number != null && StringUtils.isNotBlank(number.toString()) && number.toString().length() > 11) {
            String sequenceStr = number.toString().substring(11);
            int sequenceInt = Integer.parseInt(sequenceStr);
            sequenceInt = sequenceInt + 1;
            String newSequence = String.valueOf(sequenceInt);
            if (newSequence.length() == CommonConstant.FIVE_INT) {
                code = date.concat("0001");
            } else {
                code = date.concat(String.format("%04d", sequenceInt)); // 格式化数字为4位，不足部分用0填充
            }
        } else {
            code = date.concat("0001");
        }
        redisService.set(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER, code);
        DictInfo info = new DictInfo();
        info.setCsdm(RedisKey.MATERIAL_OUT_WAREHOUSE_NUMBER);
        info.setCsmc(code);
        portalApi.updateValueByCode(info);
        return code;
    }

    //校验出库申请 数量和库存数量比较
//    public Boolean compileQuality(MaterialALLOutboundManagement materialALLOutboundManagement) {
//        if (StringUtils.isBlank(materialALLOutboundManagement.getItemCode())) {
//            return false;
//        }
//        MaterialALLInventoryManagement one = materialALLInventoryManagementService.getOne(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
//                .eq(MaterialALLInventoryManagement::getMaterialName, materialALLOutboundManagement.getItemName())
//                .eq(MaterialALLInventoryManagement::getMaterialCode, materialALLOutboundManagement.getItemCode())
//                .last("limit 1"));
//        if (one == null) {
//            throw new ServiceException(MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getCode(), MaterialStatusCode.WARE_HOUSE_QUALITY_LESS_USE_QUALITY.getMsg());
//        }
//
//        if (one.getStockQuantity() == null) {
//            return false;
//        }
//        if (one.getStockQuantity() < materialALLOutboundManagement.getQuantity()) {
//            return false;
//        }
//        return true;
//    }


}
